package br.com.processo.bean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
import javax.inject.Inject;
import javax.inject.Named;

import org.primefaces.util.MessageFactory;

import br.com.processo.modelo.Cidade;
import br.com.processo.modelo.Estado;
import br.com.processo.modelo.Setor;
import br.com.processo.modelo.Usuario;
import br.com.processo.servico.CidadeService;
import br.com.processo.servico.EstadoService;
import br.com.processo.servico.SetorService;
import br.com.processo.servico.UsuarioService;
import br.com.processo.util.Constantes;

@Named
@SessionScoped
public class UsuarioBean implements Serializable {

	private static final long serialVersionUID = 2317223559421783515L;

	@Inject
	private UsuarioService serviceUsuario;

	@Inject
	private SetorService serviceSetor;
	
	@Inject
	private EstadoService serviceEstado;
	
	@Inject
	private CidadeService serviceCidade;
	
	private boolean loginInvalido;

	private Usuario usuario;
	
	private String nomeUsuarioLogado;
	private boolean ehAdministrador;

	private String login;
	private String senha;

	private List<Usuario> usuarios;
	
	// Tabelas internas
	private List<Estado> estados;
	private List<Cidade> cidades;
	private List<Setor> tiposSetores;


	public String cadastrarUsuario() {
		if (this.tiposSetores == null) {
			this.tiposSetores = this.serviceSetor.getTiposSetores();
		}
		
		if (this.getEstados() == null) {
			this.setEstados(this.serviceEstado.getEstados());
		}
		
		this.usuario = new Usuario();
		return Constantes.CD_USUARIO + Constantes.REDIRECT_TRUE;
	}

	public void salvarUsuario() {
		try {
			serviceUsuario.salvarUsuario(this.usuario);
			this.usuario = new Usuario();
			addMessage("growlUsuario", FacesMessage.SEVERITY_INFO,
					"usuario_cadastrado_sucesso");
		} catch (Exception e) {
			addMessage("growlUsuario", FacesMessage.SEVERITY_ERROR,
					"problema_salvar_usuario");
		}
	}

	public void validaLogin(AjaxBehaviorEvent actionEvent) {
		if (this.serviceUsuario.verificaExistenciaDeLogin(this.usuario.getLogin())) {
			this.loginInvalido = true;
			this.usuario.setLogin("");
		} else {
			this.loginInvalido = false;
		}
	}
	
	public void handleMudancaEstado() {  
        if(this.usuario.getEstado() !=null && !this.usuario.getEstado().getNome().equals("")) {
        	this.cidades = this.serviceCidade.getCidadesDoEstado(this.usuario.getEstado());
        }
        else  {
        	this.cidades = new ArrayList<Cidade>();
        }
    }  

	public void deletarUsuario() {
		if (this.usuario == null) {
			addMessage("messagesListarUsuarios", FacesMessage.SEVERITY_WARN,
					"nenhum_usuario_selecionado");
			return;
		}

		try {
			serviceUsuario.deletarUsuario(this.usuario);
			this.usuarios = serviceUsuario.getUsuariosCadastrados();
			this.usuario = null;
			addMessage("messagesListarUsuarios", FacesMessage.SEVERITY_INFO,
					"usuario_deletado_sucesso");
		} catch (Exception e) {
			e.printStackTrace();
			addMessage("messagesListarUsuarios", FacesMessage.SEVERITY_ERROR,
					"erro_deletar_usuario");
		}

	}

	public String listarUsuarios() {
		this.setUsuarios(serviceUsuario.getUsuariosCadastrados());
		return Constantes.LISTAR_USUARIOS + Constantes.REDIRECT_TRUE;
	}

	public String efetuarLogin() {
		Usuario usuario = this.serviceUsuario.efetuarLogin(this.login,
				this.senha);
		if (usuario != null) {
			this.nomeUsuarioLogado = usuario.getNome();
			this.ehAdministrador = usuario.getAdministrador();
			putInSession(Constantes.USUARIO_LOGADO, usuario);
			return Constantes.MENU_PAGE + Constantes.REDIRECT_TRUE;
		}
		addMessage("growLogin", FacesMessage.SEVERITY_ERROR,
				"login_senha_invalido");
		return "";
	}

	public void addMessage(String componente, FacesMessage.Severity tipo,
			String nomeMensagem) {
		FacesContext fc = FacesContext.getCurrentInstance();
		fc.addMessage(componente,
				MessageFactory.getMessage(nomeMensagem, tipo, new String[] {}));
	}

	public Object getFromSession(String key) {
		Map<String, Object> sessionMap = FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap();
		return sessionMap.get(key);
	}

	private void putInSession(String key, Object value) {
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put(key, value);
	}

	public Usuario getUsuario() {
		return usuario;
	}

	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public String getSenha() {
		return senha;
	}

	public void setSenha(String senha) {
		this.senha = senha;
	}

	public String getNomeUsuarioLogado() {
		return nomeUsuarioLogado;
	}

	public void setNomeUsuarioLogado(String nomeUsuarioLogado) {
		this.nomeUsuarioLogado = nomeUsuarioLogado;
	}

	public Setor getTipoSetor(String descricao) {
		return serviceSetor.getTipoSetorPorDescricao(descricao);
	}

	public List<Setor> getTiposSetores() {
		return tiposSetores;
	}

	public void setTiposSetores(List<Setor> tiposSetores) {
		this.tiposSetores = tiposSetores;
	}

	public List<Usuario> getUsuarios() {
		return usuarios;
	}

	public void setUsuarios(List<Usuario> usuarios) {
		this.usuarios = usuarios;
	}

	public boolean isLoginInvalido() {
		return loginInvalido;
	}

	public void setLoginInvalido(boolean loginInvalido) {
		this.loginInvalido = loginInvalido;
	}

	public boolean isEhAdministrador() {
		return ehAdministrador;
	}

	public void setEhAdministrador(boolean ehAdministrador) {
		this.ehAdministrador = ehAdministrador;
	}

	public List<Estado> getEstados() {
		return estados;
	}

	public void setEstados(List<Estado> estados) {
		this.estados = estados;
	}

	public List<Cidade> getCidades() {
		return cidades;
	}

	public void setCidades(List<Cidade> cidades) {
		this.cidades = cidades;
	}

	public Estado getEstadoPorNome(String nome) {
		return this.serviceEstado.getEstadoPorNome(nome);
	}

	public Cidade getCidadePorNome(String nome) {
		return this.serviceCidade.getCidadePorNome(nome);
	}

}
